import os.path
from typing import Sequence

from .attribute import Constant, Attribute
from .loader import load_shader

_current_path = os.path.dirname(__file__)


class Material:
    attributes: dict[Constant, Attribute] = {
        Constant.POSITION: Attribute('position', '3f'),
    }
    shaders = load_shader(os.path.join(_current_path, 'shader/MaterialShader.glsl'))

    def __init__(
            self,
            color: Sequence[float] = (1.0, 1.0, 1.0)
    ):
        self.color = color

    @property
    def uniforms(self):
        yield 'color', self.color


class LambertMaterial(Material):
    attributes: dict[Constant, Attribute] = {
        Constant.POSITION: Attribute('position', '3f'),
        Constant.NORMAL: Attribute('normal', '3f'),
    }
    shaders = load_shader(os.path.join(_current_path, 'shader/LambertShader.glsl'))

    def __init__(
            self,
            color: Sequence[float] = (1, 1, 1),
            radiation: Sequence[float] = (0, 0, 0),
    ):
        super().__init__(color)
        self.radiation = radiation

    @property
    def uniforms(self):
        yield 'color', self.color
        yield 'radiation', self.radiation


class LambertUVMapMaterial(LambertMaterial):
    attributes: dict[Constant, Attribute] = {
        Constant.POSITION: Attribute('position', '3f'),
        Constant.NORMAL: Attribute('normal', '3f'),
        Constant.TEXCOORD: Attribute('uv', '2f'),
    }
    shaders = load_shader(os.path.join(_current_path, 'shader/LambertUVMapShader.glsl'))

    def __init__(
            self,
            color: Sequence[float] = (1, 1, 1),
            radiation: Sequence[float] = (0, 0, 0),
            diffuse_loc: int = None
    ):
        super().__init__(color, radiation)
        self.diffuse = diffuse_loc

    @property
    def uniforms(self):
        has_diffuse = self.diffuse is not None
        yield 'color', self.color
        yield 'radiation', self.radiation
        yield 'hasdiffuse', has_diffuse
        if has_diffuse:
            yield 'diffuse', self.diffuse
